<template>
  <div class="g6_code_wrapper">
    <!-- 顶部操作栏目 -->
    <div class="top_header_warp">
      <div class="g6_toolbox">
        <!-- 导出 -->
        <div class="tollbox_item">
          <div class="icon">
            <i class="el-icon-download"></i>
          </div>
          <div class="name">导出</div>
        </div>
        <!-- 连线 -->
        <div class="tollbox_item">
          <div class="icon">
            <i class="el-icon-minus"></i>
          </div>
          <div class="name">连线</div>
        </div>
        <!-- 框选 -->
        <div class="tollbox_item">
          <div class="icon">
            <i class="el-icon-full-screen"></i>
          </div>
          <div class="name">框选</div>
        </div>
        <!-- 新建节点 -->
        <div
          class="tollbox_item"
          draggable
          @dragstart="handleDragstart"
          @dragend="handleDragEnd"
        >
          <div class="icon">
            <i class="el-icon-circle-plus-outline"></i>
          </div>
          <div class="name">节点</div>
        </div>
        <!-- 保存 -->
        <div class="tollbox_item">
          <div class="icon">
            <i class="el-icon-position"></i>
          </div>
          <div class="name" @click="saveFn()">保存</div>
        </div>
      </div>
    </div>
    <!-- 主体 -->
    <div class="g6_main_wrap">
      <!-- g6  -->
      <div class="left_content" v-loading="loading">
        <div class="node_g6" id="g6DomRef" ref="g6DomRef"></div>
      </div>
      <!-- form  -->
      <div class="right_content">
        <div class="tabbar_wrapper">
          <div
            :class="['tabbar_item', activeTabbar === item.id && 'act']"
            v-for="item in tabbarList"
            :key="item.id"
            @click="changeTabFn(item.id)"
          >
            {{ item.name }}
          </div>
        </div>
        <div class="tabbar_content">
          <component
            :is="activeTabbar"
            :propsData="propsData"
            @getG6ApiFn="getG6ApiFn"
          ></component>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import G6 from "@antv/g6";
import { v4 as uuidv4 } from "uuid";
import tab1 from "./components/tab1";
import tab2 from "./components/tab2";
import tab3 from "./components/tab3";
const commonColor = "#0077bb";
export default {
  components: {
    tab1,
    tab2,
    tab3,
  },
  data() {
    return {
      
      activeTabbar: "tab2",
      tabbarList: [
        {
          id: "tab1",
          name: "基本信息",
        },
        {
          id: "tab2",
          name: "结构信息",
        },
        {
          id: "tab3",
          name: "外键信息",
        },
      ],
      loading: false,
      offsetX: 0,
      offsetY: 0,
      graph: null,
      data: {
        nodes: [],
        edges: [],
      },
      propsData: {},
      isClickLineFlag: false, //是否点击了连线按钮
    };
  },
  beforeDestroy() {},
  created() {},
  mounted() {
    this.getG6ApiFn();
  },
  methods: {
    // 改变tabbar
    changeTabFn(id) {
      this.activeTabbar = id;
    },
    // 初始化g6
    initG6Fn() {
      G6.registerNode(
        "node_div_box", //参数名字
        {
          drawShape: function drawShape(cfg, group) {
            const size = cfg.size;
            const width = size[0];
            const height = 200;
            const shape = group.addShape("rect", {
              attrs: {
                x: -width / 2, // 左右
                y: -height / 2, // 上下
                width: width, //盒子宽度
                height: height, //盒子高度
                fill: commonColor, //背景色
                radius: [10],
              },
              draggable: true,
              name: "div的最外层",
            });
            group.addShape("text", {
              attrs: {
                x: 0, // 左右 0 是中间
                y: -height / 2 + 15, // 上下
                textBaseline: "top",
                textAlign: "center",
                lineHeight: 20,
                height: 20,
                fontSize: 16,
                text: cfg.tableName, //cfg.tableName
                fill: "#fff",
              },
              draggable: true, // 图形可拖拽
              name: "名称",
            });
            // for (let i = 0; i < 5; i++) {
            //   group.addShape("rect", {
            //     attrs: {
            //       x: -width / 2 + 10, // 左右
            //       y: -height / 2 + 40 + i * 20, // 上下 22 + i * 20
            //       width: width - 20,
            //       height: 20,
            //       fill: "#fff",
            //     },
            //     draggable: true,
            //     name: "列名的白色背景",
            //   });
            //   group.addShape("text", {
            //     attrs: {
            //       x: -width / 2 + 10 + 10, // 左右
            //       y: -height / 2 + 40 + 5 + i * 20, // 上下
            //       textBaseline: "top",
            //       lineHeight: 20,
            //       height: 20,
            //       text: `我是${i}的哈哈`, //cfg.columns[i].fieldName
            //       fill: "#555",
            //     },
            //     draggable: true, // 图形可拖拽
            //     name: "各列的文字",
            //   });
            // }
            return shape;
          },
        },
        "single-node"
      );
      const width = document.getElementById("g6DomRef").clientWidth;
      const height = document.getElementById("g6DomRef").offsetHeight;
      // 自定义节点样式
      this.graph = new G6.Graph({
        container: "g6DomRef",
        width,
        height,
        modes: {
          default: [
            // "drag-canvas", // 允许拖拽画布
            "zoom-canvas", //缩放画布
            "drag-node", //拖拽节点
            "click-select", //单选选中
          ],
        },
        // 默认的节点样式、
        defaultNode: {
          type: "node_div_box", //对标的自定义样式的name
          size: [250, 20],
          style: {
            // stroke: "#f00", //边框颜色
            lineWidth: 0, //描边粗细
            fill: commonColor,
            // radius: [0, 0, 0, 0], // 左上 右上 右下 左下
          },
          // labelCfg: {
          //   position: "bottom",
          //   offset: 8,
          //   style: {
          //     fill: commonColor,
          //     fontSize: 12,
          //   },
          // },
        },
        nodeStateStyles: {
          // 节点选中样式
          selected: {
            shadowOffsetX: 15,
            shadowOffsetY: 15,
            shadowColor: commonColor,
            shadowBlur: 50,
            opacity: 0.8,
          },
        },
      });
      // 节点的点击事件
      this.graph.on("node:click", (ev) => {
        const { item } = ev;
        this.graph.setItemState(item, "selected", true);
        let model = ev.item._cfg.model;
        let tab1Obj = { tab12: JSON.parse(JSON.stringify(model)) };
        this.propsData = { ...tab1Obj };
      });
      // 读取数据
      this.graph.data(this.data);
      // 渲染图
      this.graph.render();
    },
    //自定义连线
    createG6Line() {},
    //是否连线
    clickLineFn() {
      this.isClickLineFlag = !this.isClickLineFlag;
    },
    // 节点的拖拽创建-start
    handleDragstart(e) {
      this.offsetX = e.offsetX;
      this.offsetY = e.offsetY;
    },
    // 节点的拖拽创建-end
    handleDragEnd(e) {
      let canvas = this.$refs.g6DomRef.getElementsByTagName("canvas")[0];
      let ctx = canvas.getContext("2d");
      let jiange = canvas.getBoundingClientRect();
      console.log(e.clientX - jiange.left, e.clientY - jiange.top);
      ctx.rect(0, 0, canvas.width, canvas.height);
      console.log(
        ctx.isPointInPath(e.clientX - jiange.left, e.clientY - jiange.top)
      );
      if (ctx.isPointInPath(e.clientX - jiange.left, e.clientY - jiange.top)) {
        // 将屏幕/页面坐标转换为渲染坐标
        let UUID = uuidv4();
        const xy = this.graph.getPointByClient(e.x, e.y);
        let model = {
          id: UUID,
          tableName: "", //表名
          code: "", //编码
          textarea: "", //描述
          jiegouArr: [],
          x: xy.x,
          y: xy.y,
          offsetX: this.offsetX,
          offsetY: this.offsetY,
        };
        this.data.nodes.push(model);
        this.graph.addItem("node", model);
        this.graph.fitView = true;
      }
    },
    // 获取第一次初始数据
    getInitDataFn() {
      let data = {
        nodes: [
          {
            id: uuidv4(),
            tableName: "模拟表名1",
            code: "模拟编码1",
            textarea: "模拟描述1",
            jiegouArr: [
              {
                UID: uuidv4(),
                nameStr: "名字1-1",
                codeStr: "编码1-1",
                typeStr: "类型1-1",
                lengthStr: "长度1-1",
                accuracyStr: "精度1-1",
                defaultStr: "默认1-1",
                isNullStr: false,
                descStr: "描述1-1",
              },
              {
                UID: uuidv4(),
                nameStr: "名字1-2",
                codeStr: "编码1-2",
                typeStr: "类型1-2",
                lengthStr: "长度1-2",
                accuracyStr: "精度1-2",
                defaultStr: "默认1-2",
                isNullStr: false,
                descStr: "描述1-2",
              },
            ],
            x: 100,
            y: 100,
          },
          {
            id: uuidv4(),
            tableName: "模拟表名2",
            code: "模拟编码2",
            textarea: "模拟描述2",
            jiegouArr: [
              {
                UID: uuidv4(),
                nameStr: "名字2-1",
                codeStr: "编码2-1",
                typeStr: "类型2-1",
                lengthStr: "长度2-1",
                accuracyStr: "精度2-1",
                defaultStr: "默认2-1",
                isNullStr: false,
                descStr: "描述2-1",
              },
            ],
            x: 200,
            y: 200,
          },
          {
            id: uuidv4(),
            tableName: "模拟表名3",
            code: "模拟编码3",
            textarea: "模拟描述3",
            jiegouArr: [
              {
                UID: uuidv4(),
                nameStr: "名字3-1",
                codeStr: "编码3-1",
                typeStr: "类型3-1",
                lengthStr: "长度3-1",
                accuracyStr: "精度3-1",
                defaultStr: "默认3-1",
                isNullStr: false,
                descStr: "描述3-1",
              },
              {
                UID: uuidv4(),
                nameStr: "",
                codeStr: "",
                typeStr: "",
                lengthStr: "",
                accuracyStr: "",
                defaultStr: "",
                isNullStr: true,
                descStr: "",
              },
              {
                UID: uuidv4(),
                nameStr: "名字3-3",
                codeStr: "编码3-3",
                typeStr: "类型3-3",
                lengthStr: "长度3-3",
                accuracyStr: "精度3-3",
                defaultStr: "默认3-3",
                isNullStr: false,
                descStr: "描述3-3",
              },
            ],
            x: 300,
            y: 300,
          },
        ],
      };
      return data;
    },
    saveFn(){
      console.log(this.data)
    },
    // 获取g6的list
    getG6ApiFn(paramsObj) {
      this.loading = true;
      setTimeout(() => {
        let apiData = localStorage.getItem("g6Data") || null;
        if (!apiData) {
          apiData = JSON.stringify(this.getInitDataFn());
          localStorage.setItem("g6Data", apiData);
        }
        let parseData = JSON.parse(apiData);
        if (paramsObj) {
          let { type, obj } = paramsObj;
          if (type == "tab1") {
            let nodeArr = parseData.nodes.map((item) => {
              if (item.id === obj.id) {
                return obj;
              }
              return item;
            });
            parseData.nodes = nodeArr;
          }
        }
        this.data = parseData;
        localStorage.setItem("g6Data", JSON.stringify(parseData));
        if (!this.graph) {
          this.initG6Fn();
        } else {
          this.graph.data(this.data);
          this.graph.render();
        }
        this.loading = false;
      }, 500);
    },
  },
};
</script>

<style lang="less" scoped>
.g6_code_wrapper {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  .top_header_warp {
    flex: 0 0 auto;
    width: 100%;
    height: 80px;
    box-sizing: border-box;
    padding: 0 50px;
    display: flex;
    align-items: center;
    background-color: #e7f0fb;
    .g6_toolbox {
      display: flex;
      align-items: center;
      height: 100%;
      .tollbox_item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: 16px;
        color: #333;
        height: 100%;
        width: 80px;
        cursor: pointer;
        border-radius: 6px;
        &:hover {
          background-color: #409eff;
          color: #fff;
        }
        .icon {
          font-size: 24px;
        }
        .name {
          margin-top: 4px;
        }
      }
    }
  }
  .g6_main_wrap {
    flex: 1 1 auto;
    height: 0;
    display: flex;
    .left_content {
      flex: 1 1 auto;
      width: 0;
      .node_g6 {
        width: 100%;
        height: 100%;
      }
    }
    .right_content {
      flex: 1 1 auto;
      width: 0;
      box-sizing: border-box;
      border-left: 1px solid #ccc;
      padding: 20px;
      display: flex;
      flex-direction: column;
      .tabbar_wrapper {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        font-size: 14px;
        line-height: 30px;
        border-bottom: 1px solid #ccc;
        .tabbar_item {
          height: 100%;
          padding: 0 20px;
          cursor: pointer;
          position: relative;
          &::after {
            content: "";
            position: absolute;
            width: 80%;
            left: 50%;
            bottom: 0;
            height: 2px;
            transform: translateX(-50%);
            background-color: transparent;
          }
          &:hover,
          &.act {
            color: #409eff;
            &::after {
              background-color: #409eff;
            }
          }
        }
      }
      .tabbar_content {
        flex: 1 1 auto;
        margin-top: 20px;
        height: 0;
      }
    }
  }
}
</style>
